package tk.pak0.audiomidifier.view;

import java.awt.Color;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;

import org.apache.log4j.Logger;
import org.dyno.visual.swing.layouts.Bilateral;
import org.dyno.visual.swing.layouts.Constraints;
import org.dyno.visual.swing.layouts.GroupLayout;
import org.dyno.visual.swing.layouts.Leading;
import org.dyno.visual.swing.layouts.Trailing;

import tk.pak0.audiomidifier.controller.Controller;
import tk.pak0.audiomidifier.model.persistence.A_DataHolder;
import tk.pak0.audiomidifier.model.persistence.XmlDataHolder;

import com.nilo.plaf.nimrod.NimRODLookAndFeel;
import com.nilo.plaf.nimrod.NimRODTheme;

//VS4E -- DO NOT REMOVE THIS LINE!
public class MainWindow extends JFrame {
	private static final long serialVersionUID = -718819466008811666L;
	private static Logger log = Logger.getLogger(MainWindow.class);
	
	private Controller mainControl;
	
	private JPanel jpPrincipal;
	
	private JPanel jpConfiguracion;
	
	private JPanel jpAvanzado;
	
	private JTabbedPane jTPestanyas;
	
	private JComboBox comboTarjetas;
	private JLabel etiquetaTarjetaSonido;
	
	private JLabel etiquetaEntradaAudio;
	private JComboBox comboEntradas;
	
	private JComboBox comboSalidaAudio;
	private JLabel etiquetaSalida;
	
	private JLabel etiquetaCuantizacion;
	private JComboBox comboCuantizacion;
	private JPanel jPDirecto;
	private JPanel jPArchivo;
	private JCheckBox checkDirecto;
	private JCheckBox checkArchivo;
	private JLabel etiquetaSalidaMidi;
	private JComboBox comboSalidasMidi;
	private JLabel etiquetaArchivo;
	private JTextField TabPrincipal;
	private JButton botonBuscar;
	private JSpinner spinMetronomo;
	private JLabel etiquetaMetronomo;
	private JToggleButton botonStart;
	private JComboBox comboMidiDev;
	private JLabel etiquetaMidiDev;
	private JLabel etiquetaCompas;
	private JSpinner compasASpinner;
	private JSpinner compasBSpinner;
	private JLabel etiquetaMetroCombo;
	private JComboBox metroCombo;

	// Registro
	private JPanel jPRegistro;
	
	private JLabel etiquetaMinNote;
	private JLabel etiquetaMaxNote;
	private JComboBox comboMinNote;
	private JComboBox comboMaxNote;
	private JButton botonReset1;

	// Deteccion de pitch
	private JPanel jPPitchDet;
	
	private JLabel etiquetaMetodoPD;
	private JComboBox comboMetodoPD;

	private JLabel etiquetaNumHPS;
	private JSpinner spinNumHPS;

	private JLabel etiquetaSuavizado;
	private JSlider sliderSuavizado;

	private JComboBox comboBufferSize;

	private JLabel etiquetaBufferSize;

	private JLabel etiquetaSampleRate;

	private JComboBox comboSamplerate;

	private JLabel etiquetaResample;
	private JComboBox comboResample;

	private JCheckBox checkResample;
	
	private JButton botonReset2;

	private static final String PREFERRED_LOOK_AND_FEEL = "javax.swing.plaf.metal.MetalLookAndFeel";

	public MainWindow() {
		mainControl = Controller.getInstance();
		initComponents();
		A_DataHolder a_DataHolder = XmlDataHolder.getInstance();
		try {
			a_DataHolder.getPersistence();
			setValues(a_DataHolder.getValues());
		} catch (IOException e) {
			log.info("Lectura de persistencia fallida");
			log.info("Cargando parámetros por defecto");
			try {
				a_DataHolder.loadDefaults();
				setValues(a_DataHolder.getValues());
			} catch (IOException e1) {
				log.error("Lectura de parámetros por defecto fallida");
				e1.printStackTrace();
			}
		}
	}

	private void initComponents() {
		setLayout(new GroupLayout());
		setTitle("AudioMidifier");
		add(getJTPestanyas(), new Constraints(new Bilateral(12, 12, 5), new Bilateral(12, 12, 7)));
		setSize(488, 349);
	}

	private JCheckBox getCheckResample() {
		if (checkResample == null) {
			checkResample = new JCheckBox();
			checkResample.setText(mainControl.getProperties().getString("swing.check.resample.activate"));
			checkResample.addActionListener(new ActionListener() {
				
				public void actionPerformed(ActionEvent arg0) {
					checkResample(arg0);
				}
			});
		}
		return checkResample;
	}

	private JComboBox getComboResample() {
		if (comboResample == null) {
			comboResample = new JComboBox();
			comboResample.setModel(new DefaultComboBoxModel(mainControl.getResampleRates()));
			comboResample.setDoubleBuffered(false);
			comboResample.setBorder(null);
		}
		return comboResample;
	}

	private JButton getBotonReset2() {
		if (botonReset2 == null) {
			botonReset2 = new JButton();
			botonReset2.setText(mainControl.getProperties().getString("swing.button.reset"));
		}
		return botonReset2;
	}

	private JLabel getEtiquetaResample() {
		if (etiquetaResample == null) {
			etiquetaResample = new JLabel();
			etiquetaResample.setText(mainControl.getProperties().getString("swing.label.resample"));
		}
		return etiquetaResample;
	}

	private JComboBox getComboSamplerate() {
		if (comboSamplerate == null) {
			comboSamplerate = new JComboBox();
			comboSamplerate.setModel(new DefaultComboBoxModel(mainControl.getSampleRates()));
			comboSamplerate.setDoubleBuffered(false);
			comboSamplerate.setBorder(null);
		}
		return comboSamplerate;
	}

	private JLabel getEtiquetaSampleRate() {
		if (etiquetaSampleRate == null) {
			etiquetaSampleRate = new JLabel();
			etiquetaSampleRate.setText(mainControl.getProperties().getString("swing.label.samplerate"));
		}
		return etiquetaSampleRate;
	}

	private JLabel getEtiquetaBufferSize() {
		if (etiquetaBufferSize == null) {
			etiquetaBufferSize = new JLabel();
			etiquetaBufferSize.setText(mainControl.getProperties().getString("swing.label.buffersize"));
		}
		return etiquetaBufferSize;
	}

	private JComboBox getComboBufferSize() {
		if (comboBufferSize == null) {
			comboBufferSize = new JComboBox();
			comboBufferSize.setModel(new DefaultComboBoxModel(mainControl.getBufferSizes()));
			comboBufferSize.setDoubleBuffered(false);
			comboBufferSize.setBorder(null);
		}
		return comboBufferSize;
	}

	private JPanel getJPPitchDet() {
		if (jPPitchDet == null) {
			jPPitchDet = new JPanel();
			jPPitchDet.setLayout(new GroupLayout());
			jPPitchDet.add(getEtiquetaMetodoPD(), new Constraints(new Leading(12, 12, 12), new Leading(12, 12, 12)));
			jPPitchDet.add(getJSpinner0(), new Constraints(new Trailing(12, 291, 291), new Leading(10, 10, 10)));
			jPPitchDet.add(getEtiquetaBufferSize(), new Constraints(new Leading(12, 12, 12), new Leading(134, 12, 12)));
			jPPitchDet.add(getEtiquetaSampleRate(), new Constraints(new Leading(12, 12, 12), new Leading(105, 12, 12)));
			jPPitchDet.add(getEtiquetaSuavizado(), new Constraints(new Leading(12, 66, 230), new Leading(48, 12, 12)));
			jPPitchDet.add(getComboMetodoPD(), new Constraints(new Leading(123, 10, 10), new Leading(6, 12, 12)));
			jPPitchDet.add(getComboSamplerate(), new Constraints(new Leading(123, 12, 12), new Leading(101, 12, 12)));
			jPPitchDet.add(getComboBufferSize(), new Constraints(new Leading(123, 12, 12), new Leading(130, 12, 12)));
			jPPitchDet.add(getComboResample(), new Constraints(new Leading(320, 12, 12), new Leading(101, 12, 12)));
			jPPitchDet.add(getEtiquetaResample(), new Constraints(new Leading(241, 10, 10), new Leading(105, 12, 12)));
			jPPitchDet.add(getEtiquetaNumHPS(), new Constraints(new Leading(241, 58, 58), new Leading(12, 12, 12)));
			jPPitchDet.add(getJSlider0(), new Constraints(new Trailing(12, 81, 81), new Leading(48, 12, 12)));
			jPPitchDet.add(getCheckResample(), new Constraints(new Leading(241, 8, 8), new Leading(74, 8, 8)));
			jPPitchDet.add(getBotonReset2(), new Constraints(new Leading(320, 12, 12), new Leading(129, 12, 12)));
			String text = mainControl.getProperties().getString("swing.tab.pdmethod");
			comboMetodoPDFocusItemEvent(null);
			checkResample(null);
			jPPitchDet.setBorder(BorderFactory.createTitledBorder(null, text, TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, new Font("Dialog",
					Font.BOLD, 12), new Color(51, 51, 51)));
		}
		return jPPitchDet;
	}

	private JSlider getJSlider0() {
		if (sliderSuavizado == null) {
			sliderSuavizado = new JSlider();
		}
		return sliderSuavizado;
	}

	private JLabel getEtiquetaSuavizado() {
		if (etiquetaSuavizado == null) {
			etiquetaSuavizado = new JLabel();
			etiquetaSuavizado.setText(mainControl.getProperties().getString("swing.label.smoothing"));
		}
		return etiquetaSuavizado;
	}

	private JSpinner getJSpinner0() {
		if (spinNumHPS == null) {
			spinNumHPS = new JSpinner();
		}
		return spinNumHPS;
	}

	private JLabel getEtiquetaNumHPS() {
		if (etiquetaNumHPS == null) {
			etiquetaNumHPS = new JLabel();
			etiquetaNumHPS.setText(mainControl.getProperties().getString("swing.label.ithhps"));
		}
		return etiquetaNumHPS;
	}

	private JComboBox getComboMetodoPD() {
		if (comboMetodoPD == null) {
			comboMetodoPD = new JComboBox();
			comboMetodoPD.setModel(new DefaultComboBoxModel(mainControl.getPitchDetectionModes()));
			comboMetodoPD.setDoubleBuffered(false);
			comboMetodoPD.setBorder(null);
			Rectangle rect = comboMetodoPD.getBounds();
			rect.setSize(((int)(rect.getWidth()*0.8)), ((int)(rect.getHeight())));
			comboMetodoPD.setBounds(rect);
			comboMetodoPD.addItemListener(new ItemListener() {
				// Refrescar el listado de entradas al cambiar de tarjeta
				public void itemStateChanged(ItemEvent event) {
					comboMetodoPDFocusItemEvent(event);
				}
			});
		}
		return comboMetodoPD;
	}

	private JLabel getEtiquetaMetodoPD() {
		if (etiquetaMetodoPD == null) {
			etiquetaMetodoPD = new JLabel();
			etiquetaMetodoPD.setText(mainControl.getProperties().getString("swing.label.pdmethod"));
		}
		return etiquetaMetodoPD;
	}

	private JComboBox getComboSalidaAudio() {
		if (comboSalidaAudio == null) {
			comboSalidaAudio = new JComboBox();
			comboSalidaAudio.setModel(new DefaultComboBoxModel(mainControl.getOutputLinesNamesFromMixerIndex(0)));
			comboSalidaAudio.setDoubleBuffered(false);
			comboSalidaAudio.setBorder(null);
		}
		return comboSalidaAudio;
	}

	private JLabel getEtiquetaSalida() {
		if (etiquetaSalida == null) {
			etiquetaSalida = new JLabel();
			etiquetaSalida.setText(mainControl.getProperties().getString("swing.label.audioout"));
		}
		return etiquetaSalida;
	}

	private JPanel getJPregistro() {
		if (jPRegistro == null) {
			jPRegistro = new JPanel();
			String text = mainControl.getProperties().getString("swing.panel.title.registro");
			jPRegistro.setBorder(BorderFactory.createTitledBorder(null, text, TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, new Font("Dialog",
					Font.BOLD, 12), new Color(51, 51, 51)));
			jPRegistro.setLayout(new GroupLayout());
			jPRegistro.add(getEtiquetaMinNote(), new Constraints(new Leading(15, 10, 10), new Leading(12, 12, 12)));
			jPRegistro.add(getEtiquetaMaxNote(), new Constraints(new Leading(15, 12, 12), new Leading(44, 12, 12)));
			jPRegistro.add(getComboMinNote(), new Constraints(new Leading(221, 10, 10), new Leading(8, 12, 12)));
			jPRegistro.add(getComboMaxNote(), new Constraints(new Leading(221, 12, 12), new Leading(40, 12, 12)));
			jPRegistro.add(getBotonReset1(), new Constraints(new Trailing(12, 12, 12), new Leading(65, 12, 12)));
		}
		return jPRegistro;
	}

	private JButton getBotonReset1() {
		if (botonReset1 == null) {
			botonReset1 = new JButton();
			String text = mainControl.getProperties().getString("swing.button.reset");
			botonReset1.setText(text);
		}
		return botonReset1;
	}

	private JComboBox getComboMaxNote() {
		if (comboMaxNote == null) {
			comboMaxNote = new JComboBox();
			comboMaxNote.setModel(new DefaultComboBoxModel(mainControl.getTessitura()));
			comboMaxNote.setDoubleBuffered(false);
			comboMaxNote.setBorder(null);
			comboMaxNote.setSelectedIndex(mainControl.getTessitura().length-1);
		}
		return comboMaxNote;
	}

	private JLabel getEtiquetaMaxNote() {
		if (etiquetaMaxNote == null) {
			etiquetaMaxNote = new JLabel();
			String text = mainControl.getProperties().getString("swing.label.maxnote");
			etiquetaMaxNote.setText(text);
		}
		return etiquetaMaxNote;
	}

	private JLabel getEtiquetaMinNote() {
		if (etiquetaMinNote == null) {
			etiquetaMinNote = new JLabel();
			String text = mainControl.getProperties().getString("swing.label.minnote");
			etiquetaMinNote.setText(text);
		}
		return etiquetaMinNote;
	}

	private JComboBox getComboMinNote() {
		if (comboMinNote == null) {
			comboMinNote = new JComboBox();
			comboMinNote.setModel(new DefaultComboBoxModel(mainControl.getTessitura()));
			comboMinNote.setDoubleBuffered(false);
			comboMinNote.setBorder(null);
		}
		return comboMinNote;
	}

	private JComboBox getMetroCombo() {
		if (metroCombo == null) {
			metroCombo = new JComboBox();
			metroCombo.setModel(new DefaultComboBoxModel(mainControl.getMetronomeModes()));
			metroCombo.setDoubleBuffered(false);
			metroCombo.setBorder(null);
		}
		return metroCombo;
	}

	private JLabel getEtiquetaCombo() {
		if (etiquetaMetroCombo == null) {
			etiquetaMetroCombo = new JLabel();
			String text = mainControl.getProperties().getString("swing.label.metromode");
			etiquetaMetroCombo.setText(text);
		}
		return etiquetaMetroCombo;
	}

	private JSpinner getEtiquetaBSpinner() {
		if (compasBSpinner == null) {
			compasBSpinner = new JSpinner();
			compasBSpinner.setValue(4);
		}
		return compasBSpinner;
	}

	private JSpinner getCompasASpinner() {
		if (compasASpinner == null) {
			compasASpinner = new JSpinner();
			compasASpinner.setValue(4);
		}
		return compasASpinner;
	}

	private JLabel getEtiquetaCompas() {
		if (etiquetaCompas == null) {
			etiquetaCompas = new JLabel();
			String text = mainControl.getProperties().getString("swing.label.measure");
			etiquetaCompas.setText(text);
		}
		return etiquetaCompas;
	}

	private JLabel getEtiquetaMidiDev() {
		if (etiquetaMidiDev == null) {
			etiquetaMidiDev = new JLabel();
			String text = mainControl.getProperties().getString("swing.label.mididev");
			etiquetaMidiDev.setText(text);
		}
		return etiquetaMidiDev;
	}

	private JComboBox getComboMidiDev() {
		if (comboMidiDev == null) {
			comboMidiDev = new JComboBox();
			comboMidiDev.setModel(new DefaultComboBoxModel(mainControl.getMidiDevsNames()));
			comboMidiDev.setDoubleBuffered(false);
			comboMidiDev.setBorder(null);
//			comboMidiDev.addFocusListener(new FocusAdapter() {
//				
//				public void focusLost(FocusEvent event) {
//					comboMidiDevFocusFocusLost(event);
//				}				
//			});
		}
		return comboMidiDev;
	}

	private JToggleButton getBotonStart() {
		if (botonStart == null) {
			botonStart = new JToggleButton();
			String text = mainControl.getProperties().getString("swing.button.start");
			botonStart.setText(text);
			botonStart.addActionListener(new ActionListener() {
				// Action listener para arrancar o parar el programa
				public void actionPerformed(ActionEvent arg0) {
					arrancarParar(arg0);
				}
			});
		}
		return botonStart;
	}

	private JLabel getEtiquetaMetronomo() {
		if (etiquetaMetronomo == null) {
			etiquetaMetronomo = new JLabel();
			String text = mainControl.getProperties().getString("swing.label.bpm");
			etiquetaMetronomo.setText(text);
		}
		return etiquetaMetronomo;
	}

	private JSpinner getSpinMetronomo() {
		if (spinMetronomo == null) {
			spinMetronomo = new JSpinner();
			spinMetronomo.setValue(new Integer(100));
		}
		return spinMetronomo;
	}

	private JButton getBotonBuscar() {
		if (botonBuscar == null) {
			botonBuscar = new JButton();
			String text = mainControl.getProperties().getString("swing.button.search");
			botonBuscar.setText(text);
			botonBuscar.addMouseListener(new MouseAdapter() {
	
				public void mouseClicked(MouseEvent event) {
					botonBuscarPulsado(event);
				}
			});
		}
		return botonBuscar;
	}

	private JTextField getInputArchivo() {
		if (TabPrincipal == null) {
			TabPrincipal = new JTextField();
			TabPrincipal.setText("");
		}
		return TabPrincipal;
	}

	private JLabel getEtiquetaArchivo() {
		if (etiquetaArchivo == null) {
			etiquetaArchivo = new JLabel();
			String text = mainControl.getProperties().getString("swing.label.midifile");
			etiquetaArchivo.setText(text);
		}
		return etiquetaArchivo;
	}

	private JComboBox getComboSalidasMidi() {
		if (comboSalidasMidi == null) {
			comboSalidasMidi = new JComboBox();
			// Rellenarmos el combo de salidas midi / We fill the midi out lines combo
			comboSalidasMidi.setModel(new DefaultComboBoxModel(mainControl.getMidiDevsNames()));
			comboSalidasMidi.setDoubleBuffered(false);
			comboSalidasMidi.setBorder(null);
		}
		return comboSalidasMidi;
	}

	private JLabel getEtiquetaSalidaMidi() {
		if (etiquetaSalidaMidi == null) {
			etiquetaSalidaMidi = new JLabel();
			String text = mainControl.getProperties().getString("swing.label.midiport");
			etiquetaSalidaMidi.setText(text);
		}
		return etiquetaSalidaMidi;
	}

	private JCheckBox getCheckArchivo() {
		if (checkArchivo == null) {
			checkArchivo = new JCheckBox();
			String text = mainControl.getProperties().getString("swing.check.filemode.activate");
			checkArchivo.setText(text);
			checkArchivo.addActionListener(new ActionListener(){
				// Activar modo archivo
				public void actionPerformed(ActionEvent event) {
					checkArchivo(event);
				}
				
			});
		}
		return checkArchivo;
	}

	private JCheckBox getCheckDirecto() {
		if (checkDirecto == null) {
			checkDirecto = new JCheckBox();
			String text = mainControl.getProperties().getString("swing.check.livemode.activate");
			checkDirecto.setText(text);
			checkDirecto.setSelected(true);
			checkDirecto.addActionListener(new ActionListener(){
				// Modo directo
				public void actionPerformed(ActionEvent event) {
					checkDirecto(event);
				}
				
			});
		}
		return checkDirecto;
	}

	private JPanel getJPArchivo() {
		if (jPArchivo == null) {
			jPArchivo = new JPanel();
			jPArchivo.setBorder(BorderFactory.createTitledBorder(null, "Modo archivo", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, new Font("Dialog",
					Font.BOLD, 12), new Color(51, 51, 51)));
			jPArchivo.setLayout(new GroupLayout());
			jPArchivo.add(getEtiquetaArchivo(), new Constraints(new Leading(5, 12, 12), new Leading(19, 10, 10)));
			jPArchivo.add(getInputArchivo(), new Constraints(new Leading(100, 203, 10, 10), new Leading(17, 12, 12)));
			jPArchivo.add(getCheckArchivo(), new Constraints(new Leading(355, 10, 10), new Leading(-24, 10, 10)));
			jPArchivo.add(getEtiquetaMetronomo(), new Constraints(new Leading(5, 12, 12), new Leading(51, 12, 12)));
			jPArchivo.add(getSpinMetronomo(), new Constraints(new Leading(221, 48, 12, 12), new Leading(48, 12, 12)));
			jPArchivo.add(getBotonBuscar(), new Constraints(new Leading(338, 12, 12), new Leading(14, 12, 12)));
			jPArchivo.add(getEtiquetaCombo(), new Constraints(new Leading(290, 12, 12), new Leading(51, 12, 12)));
			jPArchivo.add(getMetroCombo(), new Constraints(new Leading(338, 82, 12, 12), new Leading(48, 12, 12)));
		}
		return jPArchivo;
	}

	private JPanel getJPDirecto() {
		if (jPDirecto == null) {
			jPDirecto = new JPanel();
			String text = mainControl.getProperties().getString("swing.panel.title.livemode");
			jPDirecto.setBorder(BorderFactory.createTitledBorder(null, text, TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, new Font("Dialog",
					Font.BOLD, 12), new Color(51, 51, 51)));
			jPDirecto.setLayout(new GroupLayout());
			jPDirecto.add(getEtiquetaSalidaMidi(), new Constraints(new Leading(14, 161, 154, 154), new Leading(31, 10, 10)));
			jPDirecto.add(getComboSalidasMidi(), new Constraints(new Leading(212, 165, 10, 10), new Leading(27, 12, 12)));
			jPDirecto.add(getCheckDirecto(), new Constraints(new Leading(356, 10, 10), new Leading(-24, 10, 10)));
		}
		return jPDirecto;
	}

	private JComboBox getComboCuantizacion() {
		if (comboCuantizacion == null) {
			comboCuantizacion = new JComboBox();
			comboCuantizacion.setModel(new DefaultComboBoxModel(mainControl.getCuantizationModes()));
			comboCuantizacion.setSelectedIndex(4);
			comboCuantizacion.setDoubleBuffered(false);
			comboCuantizacion.setBorder(null);
		}
		return comboCuantizacion;
	}

	private JLabel getEtiquetaCuantizacion() {
		if (etiquetaCuantizacion == null) {
			etiquetaCuantizacion = new JLabel();
			String text = mainControl.getProperties().getString("swing.label.cuantization");
			etiquetaCuantizacion.setText(text);
		}
		return etiquetaCuantizacion;
	}

	private JComboBox getComboEntradas() {
		if (comboEntradas == null) {
			comboEntradas = new JComboBox();
			comboEntradas.setModel(new DefaultComboBoxModel(mainControl.getInputLinesNamesFromMixerIndex(0)));
			comboEntradas.setDoubleBuffered(false);
			comboEntradas.setBorder(null);
		}
		return comboEntradas;
	}

	private JLabel getEtiquetaEntradaAudio() {
		if (etiquetaEntradaAudio == null) {
			etiquetaEntradaAudio = new JLabel();
			String text = mainControl.getProperties().getString("swing.label.audioin");
			etiquetaEntradaAudio.setText(text);
		}
		return etiquetaEntradaAudio;
	}

	private JLabel getEtiquetaTarjetaSonido() {
		if (etiquetaTarjetaSonido == null) {
			etiquetaTarjetaSonido = new JLabel();
			String text = mainControl.getProperties().getString("swing.label.audiocard");
			etiquetaTarjetaSonido.setText(text);
		}
		return etiquetaTarjetaSonido;
	}

	private JComboBox getComboTarjetas() {
		if (comboTarjetas == null) {
			comboTarjetas = new JComboBox();
			comboTarjetas.setModel(new DefaultComboBoxModel(mainControl.getSoundCardsNames()));
			comboTarjetas.setDoubleBuffered(false);
			comboTarjetas.setBorder(null);
			comboTarjetas.addItemListener(new ItemListener() {
				// Refrescar el listado de entradas al cambiar de tarjeta
				public void itemStateChanged(ItemEvent event) {
					comboTarjetasItemEvent(event);
				}
			});
		}
		return comboTarjetas;
	}

	private JTabbedPane getJTPestanyas() {
		if (jTPestanyas == null) {
			jTPestanyas = new JTabbedPane();
			String tab1 = mainControl.getProperties().getString("swing.tab.main");
			jTPestanyas.addTab(tab1, getJPPrincipal());
			String tab2 = mainControl.getProperties().getString("swing.tab.config");
			jTPestanyas.addTab(tab2, getJPConfiguracion());
			String tab3 = mainControl.getProperties().getString("swing.tab.advanced");
			jTPestanyas.addTab(tab3, getJPAvanzado());
		}
		return jTPestanyas;
	}

	private JPanel getJPAvanzado() {
		if (jpAvanzado == null) {
			jpAvanzado = new JPanel();
			jpAvanzado.setLayout(new GroupLayout());
			jpAvanzado.add(getJPPitchDet(), new Constraints(new Leading(7, 444, 12, 12), new Leading(133, 161, 10, 10)));
			jpAvanzado.add(getJPregistro(), new Constraints(new Leading(7, 444, 12, 12), new Leading(3, 124, 10, 10)));
		}
		return jpAvanzado;
	}

	private JPanel getJPConfiguracion() {
		if (jpConfiguracion == null) {
			jpConfiguracion = new JPanel();
			jpConfiguracion.setVisible(false);
			jpConfiguracion.setLayout(new GroupLayout());
			jpConfiguracion.add(getComboCuantizacion(), new Constraints(new Leading(252, 89, 12, 12), new Leading(148, 10, 10)));
			jpConfiguracion.add(getEtiquetaCuantizacion(), new Constraints(new Leading(34, 109, 12, 12), new Leading(152, 12, 12)));
			jpConfiguracion.add(getEtiquetaCompas(), new Constraints(new Leading(34, 12, 12), new Leading(195, 10, 10)));
			jpConfiguracion.add(getCompasASpinner(), new Constraints(new Leading(252, 12, 12), new Leading(190, 12, 12)));
			jpConfiguracion.add(getEtiquetaBSpinner(), new Constraints(new Leading(286, 12, 12), new Leading(190, 12, 12)));
			jpConfiguracion.add(getComboTarjetas(), new Constraints(new Leading(252, 171, 12, 12), new Leading(15, 12, 12)));
			jpConfiguracion.add(getComboEntradas(), new Constraints(new Leading(252, 170, 12, 12), new Leading(48, 12, 12)));
			jpConfiguracion.add(getComboMidiDev(), new Constraints(new Leading(252, 170, 12, 12), new Leading(116, 12, 12)));
			jpConfiguracion.add(getEtiquetaMidiDev(), new Constraints(new Leading(34, 12, 12), new Leading(120, 12, 12)));
			jpConfiguracion.add(getEtiquetaEntradaAudio(), new Constraints(new Leading(34, 127, 12, 12), new Leading(52, 12, 12)));
			jpConfiguracion.add(getEtiquetaTarjetaSonido(), new Constraints(new Leading(34, 165, 12, 12), new Leading(19, 12, 12)));
			jpConfiguracion.add(getEtiquetaSalida(), new Constraints(new Leading(34, 12, 12), new Leading(84, 12, 12)));
			jpConfiguracion.add(getComboSalidaAudio(), new Constraints(new Leading(252, 170, 12, 12), new Leading(80, 12, 12)));
		}
		return jpConfiguracion;
	}

	private JPanel getJPPrincipal() {
		if (jpPrincipal == null) {
			jpPrincipal = new JPanel();
			jpPrincipal.setLayout(new GroupLayout());
			jpPrincipal.add(getJPDirecto(), new Constraints(new Leading(12, 437, 12, 12), new Leading(129, 111, 12, 12)));
			jpPrincipal.add(getJPArchivo(), new Constraints(new Leading(15, 434, 12, 12), new Leading(12, 111, 12, 12)));
			jpPrincipal.add(getBotonStart(), new Constraints(new Leading(178, 12, 12), new Leading(258, 12, 12)));
		}
		return jpPrincipal;
	}

	public static void installLnF(String theme) {
		try {
			NimRODTheme nt = new NimRODTheme(theme);
			NimRODLookAndFeel nf = new NimRODLookAndFeel();
			NimRODLookAndFeel.setCurrentTheme( nt);
			UIManager.setLookAndFeel( nf);
			
		} catch (Exception e) {
			log.error("Cannot install " + PREFERRED_LOOK_AND_FEEL
					+ " on this platform:" + e.getMessage());
		}
	}

	private void botonBuscarPulsado(MouseEvent event) {
		log.debug("Botón de búsqueda de archivo pulsado");
	}

	/**
	 * @param event
	 */
	private void comboTarjetasItemEvent(ItemEvent event) {
		JComboBox combo;
		try{
			combo= (JComboBox)event.getItemSelectable();
		}catch (NullPointerException np){
			combo = comboTarjetas;
		}
		int index = combo.getSelectedIndex();
		
		// Rellenarmos el combo de entradas de audio / We fill the source audio lines combo
		comboEntradas.setModel(new DefaultComboBoxModel(mainControl.getInputLinesNamesFromMixerIndex(index)));
		comboSalidaAudio.setModel(new DefaultComboBoxModel(mainControl.getOutputLinesNamesFromMixerIndex(index)));
	}
	
	private void comboMetodoPDFocusItemEvent(ItemEvent event) {
		JComboBox combo;
		try{
			combo= (JComboBox)event.getItemSelectable();
		}catch (NullPointerException ex){
			combo = comboMetodoPD;
		}
		
		String value = (String)combo.getSelectedItem();
		String expected1 = mainControl.getProperties().getString("swing.combo.pitchdetection.option1");
		String expected2 = mainControl.getProperties().getString("swing.combo.pitchdetection.option3");
		
		if(value.equals(expected1) || value.equals(expected2)){
			spinNumHPS.setEnabled(false);
		}else{
			spinNumHPS.setEnabled(true);
		}
		
		if(value.equals(expected2)){
			checkResample.setEnabled(false);
			comboResample.setEnabled(false);
		}else{
			checkResample.setEnabled(true);
			comboResample.setEnabled(true);
		}
	}
	
	private void arrancarParar(ActionEvent event) {
		JToggleButton button = (JToggleButton) event.getSource();
		// ponemos las líneas en el control
		mainControl.setLineaEntradaSel(comboTarjetas.getSelectedIndex(), comboEntradas.getSelectedIndex());
		mainControl.setLineaSalidaSel(comboTarjetas.getSelectedIndex(), comboSalidaAudio.getSelectedIndex());
		if(button.isSelected()){
			String text = mainControl.getProperties().getString("swing.button.stop");
			button.setText(text);
			A_DataHolder dataHolder = XmlDataHolder.getInstance();
			dataHolder.setValues(getValues());
			mainControl.startStop(true);
		}else{
			String text = mainControl.getProperties().getString("swing.button.start");
			button.setText(text);
			mainControl.startStop(false);
		}
	}
	
	private void checkDirecto(ActionEvent event){
		boolean state = checkDirecto.isSelected();
		if(state){
			checkArchivo.setSelected(false);
		}else{
			checkArchivo.setSelected(true);
		}
	}
	
	private void checkArchivo(ActionEvent event){
		boolean state = checkArchivo.isSelected();
		if(state){
			checkDirecto.setSelected(false);
		}else{
			checkDirecto.setSelected(true);
		}
	}
	
	private void checkResample(ActionEvent event){
		boolean state = checkResample.isSelected();
		if(state){
			comboResample.setEnabled(true);
		}else{
			comboResample.setEnabled(false);
		}
	}
	
	public Map<String,String> getValues(){
		Map<String,String> ret = new HashMap<String, String>();
		
		// Principal
		ret.put("bpm", String.valueOf(spinMetronomo.getValue()));
		ret.put("liveMode", String.valueOf(checkDirecto.isSelected()));
		ret.put("midioutPort", String.valueOf(comboSalidasMidi.getSelectedIndex()));
		
		// Configuración
		ret.put("soundCard", String.valueOf(comboTarjetas.getSelectedIndex()));
		ret.put("audioInput", String.valueOf(comboEntradas.getSelectedIndex()));
		ret.put("audioOutput", String.valueOf(comboSalidaAudio.getSelectedIndex()));
		ret.put("midiDevice", String.valueOf(comboMidiDev.getSelectedIndex()));
		ret.put("cuantize", String.valueOf(comboCuantizacion.getSelectedIndex()));
		ret.put("highMeasureNibble", String.valueOf(compasASpinner.getValue()));
		ret.put("lowMeasureNibble", String.valueOf(compasBSpinner.getValue()));
		
		// Avanzado
		ret.put("maxNote", String.valueOf(comboMaxNote.getSelectedIndex()));
		ret.put("minNote", String.valueOf(comboMinNote.getSelectedIndex()));
		
		ret.put("pDMethod", String.valueOf(comboMetodoPD.getSelectedIndex()));
		ret.put("hptIt", String.valueOf(spinNumHPS.getValue()));
		ret.put("smooth", String.valueOf(sliderSuavizado.getValue()));
		ret.put("checkResample", String.valueOf(checkResample.isSelected()));
		ret.put("sampleRate", String.valueOf(comboSamplerate.getSelectedIndex()));
		ret.put("downSampleRate", String.valueOf(comboResample.getSelectedIndex()));
		ret.put("bufferSize", String.valueOf(comboBufferSize.getSelectedIndex()));
		
		return ret;
	}
	
	public void setValues(Map<String,String> values){	
		// Principal
		spinMetronomo.setValue(Integer.parseInt(values.get("bpm")));
		checkDirecto.setSelected(Boolean.parseBoolean(values.get("liveMode")));
		// comboSalidasMidi.setSelectedIndex(Integer.parseInt(values.get("midioutPort")));
		
		// Configuración
//		comboTarjetas.setSelectedIndex(Integer.parseInt(values.get("soundCard")));
//		comboEntradas.setSelectedIndex(Integer.parseInt(values.get("audioInput")));
//		comboSalidaAudio.setSelectedIndex(Integer.parseInt(values.get("audioOutput")));
//		comboMidiDev.setSelectedIndex(Integer.parseInt(values.get("midiDevice")));
		comboCuantizacion.setSelectedIndex(Integer.parseInt(values.get("cuantize")));
		compasASpinner.setValue(Integer.parseInt(values.get("highMeasureNibble")));
		compasBSpinner.setValue(Integer.parseInt(values.get("lowMeasureNibble")));
		
		// Avanzado
		comboMaxNote.setSelectedIndex(Integer.parseInt(values.get("maxNote")));
		comboMinNote.setSelectedIndex(Integer.parseInt(values.get("minNote")));
		
		comboMetodoPD.setSelectedIndex(Integer.parseInt(values.get("pDMethod")));
		spinNumHPS.setValue(Integer.parseInt(values.get("hptIt")));
		sliderSuavizado.setValue(Integer.parseInt(values.get("smooth")));
		checkResample.setSelected(Boolean.parseBoolean(values.get("checkResample")));
		comboSamplerate.setSelectedIndex(Integer.parseInt(values.get("sampleRate")));
		comboResample.setSelectedIndex(Integer.parseInt(values.get("downSampleRate")));
		comboBufferSize.setSelectedIndex(Integer.parseInt(values.get("bufferSize")));
		
		this.comboTarjetasItemEvent(null);
		this.comboMetodoPDFocusItemEvent(null);
		this.checkDirecto(null);
		this.checkResample(null);
	}
	
//	private void comboMidiDevFocusFocusLost(FocusEvent event) {
////		JComboBox combo = (JComboBox)event.getComponent();
////		int index = combo.getSelectedIndex();
//		
//		// Rellenarmos el combo de salidas midi / We fill the midi out lines combo
////		comboSalidasMidi.setModel(new DefaultComboBoxModel(mainControl.getMidiLinesNamesFromDevIndex(index)));
//		comboSalidasMidi.setModel(new DefaultComboBoxModel(new String[]{"foo","basr"}));
//	}
}
